/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package be.ugent.medirem.logic;

import be.ugent.medirem.persistence.entity.details.MeasurementDetails;
import be.ugent.medirem.persistence.entity.details.MeasurementTypeDetails;
import be.ugent.medirem.persistence.entity.values.MeasurementTypeValues;
import be.ugent.medirem.persistence.entity.values.MeasurementValues;
import be.ugent.medirem.persistence.exception.EntityNotFoundException;
import be.ugent.medirem.persistence.facade.MeasurementDaoLocal;
import be.ugent.medirem.persistence.facade.MeasurementTypeDaoLocal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.security.RolesAllowed;
import javax.ejb.EJB;
import javax.ejb.Stateless;

/**
 *
 * @author Thomas Roelens
 */
@Stateless
public class MeasurementBean implements MeasurementRemote {

    @EJB
    private MeasurementTypeDaoLocal measurementTypeDaoBean;
    @EJB
    private MeasurementDaoLocal measurementDaoBean;

    @RolesAllowed({"gp", "patient"})
    public void addMeasurement(Long patientId, MeasurementValues details) {
        try {
            // Create the measurement
            Long mId = measurementDaoBean.create(details);

            // Add the measurement
            measurementDaoBean.addMeasurement(patientId, mId);
        } catch (IllegalArgumentException ex) {
            Logger.getLogger(MeasurementBean.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    @RolesAllowed({"gp"})
    public void removeMeasurement(Long patientId, Long measurementId) {
        try {
            measurementDaoBean.removeMeasurement(patientId, measurementId);
            measurementDaoBean.remove(measurementId);
        } catch (IllegalArgumentException ex) {
            Logger.getLogger(MeasurementBean.class.getName()).log(Level.SEVERE, null, ex);
        } catch (EntityNotFoundException ex) {
            Logger.getLogger(MeasurementBean.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @RolesAllowed({"gp", "patient"})
    public List<MeasurementDetails> getMeasurements(Long patientId, String measurementType) {
        return measurementDaoBean.getMeasurements(patientId, measurementType);
    }

    @RolesAllowed({"gp", "patient"})
    public void updateMeasurement(MeasurementValues details) {
        try {
            measurementDaoBean.update(details.getId(), details);
        } catch (IllegalArgumentException ex) {
            Logger.getLogger(MeasurementBean.class.getName()).log(Level.SEVERE, null, ex);
        } catch (EntityNotFoundException ex) {
            Logger.getLogger(MeasurementBean.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @RolesAllowed({"gp"})
    public Long createMeasurementType(MeasurementTypeValues details) throws IllegalArgumentException {
        return measurementTypeDaoBean.create(details);
    }

    @RolesAllowed({"gp"})
    public void removeMeasurementType(Long id) throws IllegalArgumentException, EntityNotFoundException {
        measurementTypeDaoBean.remove(id);
    }

    @RolesAllowed({"gp", "patient"})
    public MeasurementTypeDetails getMeasurementType(Long id) throws IllegalArgumentException {
        return measurementTypeDaoBean.getMeasurementType(id);
    }

    @RolesAllowed({"gp", "patient"})
    public List<MeasurementTypeDetails> getAllMeasurementTypes() {
        return measurementTypeDaoBean.getAll();
    }

    @RolesAllowed({"gp", "patient"})
    public MeasurementDetails getLatestMeasurement(Long patientId, String measurementType) {
        List<MeasurementDetails> list = this.getMeasurements(patientId, measurementType);
        MeasurementDetails lastMeasurement = null;
        Date best = null;

        for (MeasurementDetails m : list) {
            if (best == null) {
                // First measurement in list
                best = m.getDateTaken();
                lastMeasurement = m;
            } else {
                Date next = m.getDateTaken();
                if (best.before(next)) {
                    best = next;
                    lastMeasurement = m;
                }
            }
        }

        return lastMeasurement;
    }

    @RolesAllowed({"gp", "patient"})
    public List<MeasurementDetails> getAllMeasurements(Long patientId) {
        List<MeasurementDetails> allMeasurements = new ArrayList<MeasurementDetails>();

        for (MeasurementTypeDetails d : this.getAllMeasurementTypes()) {
            allMeasurements.addAll(this.getMeasurements(patientId, d.getName()));
        }

        return allMeasurements;
    }

    @RolesAllowed({"gp", "patient"})
    public String getMeasurementTypeUnit(String measurementType) {
        Long id = null;
        try {
            id = measurementTypeDaoBean.getMeasurementTypeId(measurementType);
        } catch (IllegalArgumentException ex) {
            Logger.getLogger(MeasurementBean.class.getName()).log(Level.SEVERE, null, ex);
        } catch (EntityNotFoundException ex) {
            Logger.getLogger(MeasurementBean.class.getName()).log(Level.SEVERE, null, ex);
        }
        if (id == null) {
            return null;
        }
        return measurementTypeDaoBean.getMeasurementType(id).getUnit();
    }

    @RolesAllowed({"gp", "patient"})
    public MeasurementDetails getMeasurementDetails(Long measurementId) throws EntityNotFoundException {
        return measurementDaoBean.getDetails(measurementId);
    }
}
